/*
 * @(#)DomUtil.java
 *
 *
 *
 * ver 1.0 Jul 16, 2007 ggranum
 */
package org.testfire.util;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class DomUtil
{

    public static final SimpleDateFormat DATE_TIME_FORMAT = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSSZ" );
    public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat( "yyyy-MM-dd" );



    public static List<Element> getChildElements( Element el )
    {
        NodeList list = el.getChildNodes();
        List<Element> children = new ArrayList<Element>();
        for ( int i = 0, n = list.getLength(); i < n; ++i )
        {
            if ( list.item( i ).getNodeType() == Node.ELEMENT_NODE )
            {
                children.add( (Element)list.item( i ) );
            }
        }
        return children;
    }

    public static List<Element> getChildElementsByTagName( String name, Element el )
    {
        NodeList list = el.getChildNodes();
        ArrayList<Element> children = new ArrayList<Element>();
        for ( int i = 0, n = list.getLength(); i < n; ++i )
        {
            Node nd = list.item( i );
            if ( nd.getNodeType() == Node.ELEMENT_NODE && nd.getNodeName().equals( name ) )
            {
                children.add( (Element)nd );
            }
        }
        return children;
    }

    /**
     * Get the first element, if present.
     * @param el The parent.
     * @return The first Element or null.
     */
    public static Element getChildElement( Element el )
    {
        Node n = el.getFirstChild();
        while ( n != null && n.getNodeType() != Node.ELEMENT_NODE )
        {
            n = n.getNextSibling();
        }
        return (Element)n;
    }

    /**
     * Get the first element with the name <code>name</code>, if present.
     * @param name the name of the child element.
     * @param el The parent.
     * @return The first Element or null.
     */
    public static Element getChildElementByTagName( String name, Element el )
    {
        Node n = el.getFirstChild();
        while ( n != null &&
            !(n.getNodeType() == Node.ELEMENT_NODE && n.getNodeName().equals( name )) )
        {
            n = n.getNextSibling();
        }
        return (Element)n;
    }

    /**
     * Get the text of the first element with the name <code>name</code>, if present, or
     * null if the node is not present.
     * @param name the name of the child element.
     * @param el The parent.
     * @return The first Element or null.
     */
    public static String getChildElementTextByTagName( String name, Element el )
    {
        Node n = el.getFirstChild();
        while ( n != null &&
            !(n.getNodeType() == Node.ELEMENT_NODE && n.getNodeName().equals( name )) )
        {
            n = n.getNextSibling();
        }
        return n == null ? "" : n.getTextContent();
    }

    /**
     * Get the name of the element, minus namespace.
     * @param node The node of interest.
     * @return The name of hte element, no namespace
     */
    public static String getName( Node node )
    {
        String name = node.getNodeName();
        int idx = name.indexOf( ":" );
        if ( idx >= 0 )
        {
            name = name.substring( idx + 1 );
        }
        return name;
    }


/**
     * Parse an xml based date string to a java.util.Date object.
     * @param xmlDate A date object in standard xml format ( "yyyy-MM-dd" );
     * @return A date object.
     * @throws IllegalArgumentException If there is an exception while parsing the passed value.
     */
    public static Date toJavaDate( String xmlDate )
    {
        try
        {
            return DatatypeFactory.newInstance().newXMLGregorianCalendar(xmlDate).toGregorianCalendar().getTime();
        }
        catch ( DatatypeConfigurationException e )
        {
            throw new IllegalArgumentException( e );
        }
    }

    /**
     * Format a Java Date object to a Date string of standard xml date format ( "yyyy-MM-dd" ).
     * @param date The date.
     * @return A valid XML Date string.
     */
    public static String toXMLDate(Date date){
        return DATE_FORMAT.format( date );
    }

    /**
     * Format a Java Date object to a Date string of standard xml date-time format  "yyyy-MM-dd'T'HH:mm:ss.SSSZ" .
     * @param date The date.
     * @return A valid XML Date string.
     */
    public static String toXMLDateTime(Date date){
        StringBuilder s = new StringBuilder(DATE_TIME_FORMAT.format( date ));
        int start = s.length() - 2;
        return s.replace( start, s.length(), ":" + s.subSequence( start, start+2 )).toString();
    }
}

// eof: DomUtil.java